﻿using System.Collections.Generic;
using System.Threading.Tasks;
using hundsun.t2sdk;
using NLog;

namespace QuantBox.XApi
{
    internal class FunctionCallback : UfxCallbackInterface
    {
        internal static readonly HashSet<int> fatalError = new HashSet<int> {
            1000, 2001, 2002, 10009, 20001, 20002
        };

        private readonly UfxClient _client;
        private readonly Logger _logger;

        public FunctionCallback(UfxClient client)
        {
            _client = client;
            _logger = client.logger;
        }

        public override void OnClose(CT2Connection lpConnection)
        {
            _logger.Trace(nameof(OnClose));
            _client.statusPublisher.Post(ConnectionStatus.Disconnected);
        }

        public override void OnSafeConnect(CT2Connection lpConnection)
        {
            _logger.Trace(nameof(OnSafeConnect));
        }

        public override void OnError(int errCode, string errMsg)
        {
            _logger.Error($"{nameof(OnError)},{errCode},{errMsg}");
        }

        public override void OnRegister(CT2Connection lpConnection)
        {
            _logger.Trace(nameof(OnRegister));
        }

        public override void OnConnect(CT2Connection lpConnection)
        {
            _logger.Trace(nameof(OnConnect));
        }

        public override unsafe void OnReceivedBizMsg(CT2Connection lpConnection, int hSend, CT2BizMessage lpMsg)
        {
            if (!_client.Connected) {
                return;
            }

            var functionId = lpMsg.GetFunction();
            var ret = lpMsg.GetReturnCode();
            if (ret == 1 || ret == -1) {
                _client.logger.Error($"交易回调错误,{UfxNames.GetFunctionName(functionId)},{lpMsg.GetErrorInfo()}");
                return;
            }

            var len = 0;
            var content = lpMsg.GetContent(&len);
            var unPacker = new CT2UnPacker(content, (uint)len);
            var error = unPacker.ReadErrorInfo(functionId);
            if (error != UfxErrorInfo.Ok) {
                _logger.Error($"{nameof(OnReceivedBizMsg)},{error.ErrCode},{error.ErrMsg}");
                if (fatalError.Contains(error.ErrCode)) {
                    _logger.Error($"严重错误关闭链接");
                    Task.Run(_client.Disconnect);
                }
            }
            OnCallback(lpConnection, hSend, functionId, unPacker);
        }

        protected override void OnReceived91004(CT2Connection lpConnection, int hSend, int functionId, Ufx91004Result[] data)
        {
            if (data.Length > 0) {
                _client.dealProcessor.PostOrderRsp(data[0]);
            }
        }

        #region Query Response

        protected override void OnReceived30010(CT2Connection lpConnection, int hSend, int functionId, Ufx30010Result[] data)
        {
            _client.queryManager.Post(functionId, data);
        }

        protected override void OnReceived31001(CT2Connection lpConnection, int hSend, int functionId, Ufx31001Result[] data)
        {
            _client.queryManager.Post(functionId, data);
        }

        protected override void OnReceived31003(CT2Connection lpConnection, int hSend, int functionId, Ufx31003Result[] data)
        {
            _client.queryManager.Post(functionId, data);
        }

        protected override void OnReceived31004(CT2Connection lpConnection, int hSend, int functionId, Ufx31004Result[] data)
        {
            _client.queryManager.Post(functionId, data);
        }

        protected override void OnReceived33001(CT2Connection lpConnection, int hSend, int functionId, Ufx33001Result[] data)
        {
            _client.queryManager.Post(functionId, data);
        }

        protected override void OnReceived33003(CT2Connection lpConnection, int hSend, int functionId, Ufx33003Result[] data)
        {
            _client.queryManager.Post(functionId, data);
        }

        protected override void OnReceived33004(CT2Connection lpConnection, int hSend, int functionId, Ufx33004Result[] data)
        {
            _client.queryManager.Post(functionId, data);
        }

        protected override void OnReceived32001(CT2Connection lpConnection, int hSend, int functionId, Ufx32001Result[] data)
        {
            _client.queryManager.Post(functionId, data);
        }

        protected override void OnReceived32003(CT2Connection lpConnection, int hSend, int functionId, Ufx32003Result[] data)
        {
            _client.queryManager.Post(functionId, data);
        }

        protected override void OnReceived32004(CT2Connection lpConnection, int hSend, int functionId, Ufx32004Result[] data)
        {
            _client.queryManager.Post(functionId, data);
        }

        protected override void OnReceived34001(CT2Connection lpConnection, int hSend, int functionId, Ufx34001Result[] data)
        {
            _client.queryManager.Post(functionId, data);
        }

        protected override void OnReceived34003(CT2Connection lpConnection, int hSend, int functionId, Ufx34003Result[] data)
        {
            _client.queryManager.Post(functionId, data);
        }

        protected override void OnReceived34004(CT2Connection lpConnection, int hSend, int functionId, Ufx34004Result[] data)
        {
            _client.queryManager.Post(functionId, data);
        }

        protected override void OnReceived35024(CT2Connection lpConnection, int hSend, int functionId, Ufx35024Result[] data)
        {
            _client.queryManager.Post(functionId, data);
        }

        protected override void OnReceived35025(CT2Connection lpConnection, int hSend, int functionId, Ufx35025Result[] data)
        {
            _client.queryManager.Post(functionId, data);
        }

        #endregion
    }
}